package lib.base;

import java.net.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import lib.data.Customer;
import lib.data.Employee;

/**
 * The Class EgoAuth for the authentication with google-account
 * 
 * @see http://code.google.com/intl/de-DE/apis/accounts/docs/OpenID.html
 * @author jonas
 *
 */
public class EgoAuth
{
	private boolean _logged;
	
	/** The request. */
	private HttpServletRequest _request = null;

	/**
	 * Instantiates a new ego auth.
	 */
	public EgoAuth(HttpServletRequest request)
	{
		_request = request;
		_logged = false;
	}

	/**
	 * Starts the login routine.
	 * 
	 * If not already logged in, make an authentication request
	 * If the account information is received, start the session
	 * 
	 * @throws Exception
	 * @return Boolean
	 */
	public boolean start() throws Exception
	{
		// is there already a session?
		HttpSession session = _request.getSession(false);
		if (
			session != null &&
			session.getAttribute("email") != null &&
			_request.getParameter("login") == null
		) {
			// we are logged in
			_logged=true;
			return isLogged();
		}
		
		// no session
		try {
			if (_request.getParameter("openid.claimed_id") == null)
			{
				this._authRequest();
			} else
			{ // extract the information returned by Google
		        session = _request.getSession(true);
		        
		        // set session time (in seconds) to 14 days
		        // A negative time indicates the session should never timeout.
		        session.setMaxInactiveInterval(60*60*24*14);
		        
		        String email = _request.getParameter("openid.ext1.value.email");
		        session.setAttribute("email", email);
		        String language = _request.getParameter("openid.ext1.value.language");
		        session.setAttribute("language", language);
				_request.setAttribute("close", true);
			}
		} catch (Exception e)
		{
			System.out.println("Exception: ["+e.toString()+"]\n"+e.getMessage());
		}
		return isLogged();
	}
	
	/**
	 * Request Google User to Sign in and allow to get user information
	 * @throws Exception
	 */
	private void _authRequest() throws Exception
	{
		/*
		 * get the discovery target URL to retrieve a valid XRDS document
		 * containing the Google OpenID endpoint.
		 */
		String content_str = EgoSystem.httpRequest("https://www.google.com/accounts/o8/id");
		
		// find URI of OpenID endpoint
		String endpointer = null;
		String patt = "<URI>([^<]+)</URI>";
		Pattern r = Pattern.compile(patt);
		Matcher m = r.matcher(content_str);
		if (m.find())
		{
			endpointer = m.group(1);
		} else
		{
			throw new Exception("No endpoint URI found");
		}
		
		String return_to = 
			EgoSystem.config.get("host").toString()
			+ EgoSystem.config.get("path").toString()
			+ "html?login=1&mdl="+_request.getParameter("mdl");
		String url_str = endpointer +
						"?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0" +
						"&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select" +
						"&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select" +
						"&openid.return_to=" + URLEncoder.encode(return_to, "UTF-8") +
						"&openid.realm=" + URLEncoder.encode(EgoSystem.config.get("host").toString(), "UTF-8") +
						"&openid.mode=checkid_setup" +
						"&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0" +
						"&openid.ax.mode=fetch_request" +
						"&openid.ax.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail" +
						"&openid.ax.type.language=http%3A%2F%2Faxschema.org%2Fpref%2Flanguage" +
						"&openid.ax.required=email,language";
		
		_request.setAttribute("redirect_url", url_str);
	}
	
	/**
	 * Checks if is logged.
	 * 
	 * @return true, if is logged
	 */
	public boolean isLogged()
	{
		return _logged;
	}
	
	public boolean isAdmin() throws Exception
	{
		if (!_logged) return false;
		
		Employee curEmp = (Employee) _request.getSession().getAttribute("currentEmployee");
		Customer curCust = (Customer) _request.getSession().getAttribute("currentCustomer");
		
		if (curEmp == null && curCust.getField("systemAccount").toString().equals( _request.getSession().getAttribute("email")))
		{
			return true;
		} else if (curEmp.getField("isAdmin").toString() == "true")
		{
			return true;
		}
		
		// otherwise
		return false;
	}
}
